/*
 * @(#)DomconOzOutputCodec.java created 03.02.2006
 * 
 * Copyright (c) 2006 Alexander Koller
 *  
 */

package de.saar.chorus.domgraph.codec.domcon;

import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

import org._3pq.jgrapht.Edge;

import de.saar.basic.StringTools;
import de.saar.chorus.domgraph.GlobalDomgraphProperties;
import de.saar.chorus.domgraph.codec.CodecMetadata;
import de.saar.chorus.domgraph.codec.CodecTools;
import de.saar.chorus.domgraph.codec.MalformedDomgraphException;
import de.saar.chorus.domgraph.codec.MultiOutputCodec;
import de.saar.chorus.domgraph.graph.DomGraph;
import de.saar.chorus.domgraph.graph.EdgeType;
import de.saar.chorus.domgraph.graph.NodeLabels;
import de.saar.chorus.domgraph.graph.NodeType;

/**
 * An output codec for weakly normal dominance constraints in Oz syntax.
 * For further documentation of this format, see {@link de.saar.chorus.domgraph.codec.domcon.DomconOzInputCodec}.
 * 
 * 
 * @author Alexander Koller
 *
 */
@CodecMetadata(name="domcon-oz", extension=".clls")
public class DomconOzOutputCodec extends MultiOutputCodec {
	@Override
    public void encode(DomGraph graph, NodeLabels labels, Writer writer)
            throws IOException, MalformedDomgraphException {
        List<String> atoms = new ArrayList<String>();
        
    	if( !graph.isLabellingConsistent(labels)) {
    		throw new MalformedDomgraphException("Graph labelling information is inconsistent with node labels.");
    	}
        
        // iterate through the labelled nodes and output labelling atoms for them
        for( String node : graph.getAllNodes() ) {
            if( graph.getData(node).getType() == NodeType.LABELLED ) {
                StringBuilder sb = 
                    new StringBuilder("label(" + CodecTools.atomify(node) + " " 
                            + CodecTools.atomify(labels.getLabel(node)));
                
                
                List<String> children = graph.getChildren(node, EdgeType.TREE);
                if( !children.isEmpty() ) {
                    sb.append("(" + CodecTools.atomify(children.get(0)));
                    
                    for( int i = 1; i < children.size(); i++ ) {
                    	sb.append(" " + CodecTools.atomify(children.get(i)));
                    }
                    
                    sb.append(")");
                }
                
                sb.append(")");
                
                atoms.add(sb.toString());
            }
        }
        
        // iterate through the dominance edges and output dominance atoms for them
        for( Edge edge : graph.getAllEdges() ) {
            if( graph.getData(edge).getType() == EdgeType.DOMINANCE ) {
                atoms.add("dom(" + CodecTools.atomify((String) edge.getSource()) 
                		+ " " + CodecTools.atomify((String) edge.getTarget()) + ")");
            }
        }
        
        writer.write("[" + StringTools.join(atoms, " ") + "]\n");
        writer.flush();
    }
    
    
    
	@Override
    public void print_header(Writer writer) throws IOException {
        writer.write("%%  autogenerated by "
                + GlobalDomgraphProperties.getSystemName()
                + " (see " + GlobalDomgraphProperties.getHomepage()
                + " for details)\n");
    }

	@Override
    public void print_footer(Writer writer) throws IOException {
        writer.flush();
    }

	@Override
    public void print_start_list(Writer writer) throws IOException {
        writer.write( "[\n");
    }

	@Override
    public void print_end_list(Writer writer) throws IOException {
        writer.write("]\n");
    }

	@Override
    public void print_list_separator(Writer writer) throws IOException {
    }
    


}
